package com.gupaoedu.vip.pattern.proxy.dynamicproxy;

import com.gupaoedu.vip.pattern.proxy.Person;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 动态代理 可以代理任何对象，然后可以在调用对象之前和之后做一些事情，而不用每次重复去写一些代码。
 *
 * JDK的动态代理：首先一个类必须实现一个接口，并且重写接口的方法，在实现动态代理的时候，会生成一个类来实现需要代理的类的接口，然后重写其方法
 * 处理逻辑，然后调用接口的实现类的方法。来实现动态代理。
 * 业务场景 有，实现动态的数据源切换。但是数据源切换的参数必须指定。
 *
 * cglib动态代理，通过Enhancer来动态生成一个类去集成需要代理的类，然后处理逻辑去调用父类的方法，实现动态代理。
 *
 * 两者的区别，JDK的动态代理，编译的效率高，带上执行的效率低，因为是通过反射来去调用方法。
 * CGLIB 编译的效率低，但是调用执行的效率高，
 *
 * 代理模式的缺点，增加了类的数量，降低了程序的执行效率。增加了系统的复杂度。
 * 优点：代理模式能将代理对象与目标对象分离，降低了系统的耦合性，易于扩展。、
 * 保护目标对象，增加了目标对象的职责。
 */
public class JDKProxyPlayer implements InvocationHandler {

    private Object person;

    public Object getInstance(Object person){
        this.person = person;
        Class<?> clazz = person.getClass();
        return Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this);
    }


    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(args[0]);
        before();
        Object o = method.invoke(this.person,args);
        after();
        return o;
    }

    public void before(){
        System.out.println("我是代练，开始帮你练级");
    }

    public void after(){
        System.out.println("练级完成，交钱");
    }
}
